package com.wonder.app.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.admin.service.IVtuzxKingdeeService;
import com.wonder.admin.service.impl.VtuzxKingdeeServiceImpl;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.SfcOperpDao;
import com.wonder.app.mapper.SfcOperpDetailDao;
import com.wonder.app.mapper.SyncOrderDetailDao;
import com.wonder.app.request.SfcOperpRequest;
import com.wonder.app.service.*;
import com.wonder.bean.kingdee.VtuzxKingdeeCloudClient;
import com.wonder.bean.kingdee.xqc.VtuzxArrayList;
import com.wonder.common.common.AjaxResult;
import com.wonder.common.utils.DateUtils;
import com.wonder.common.utils.MessageUtils;
import com.wonder.common.utils.StringUtils;
import com.wonder.constant.BillType;
import com.wonder.constant.IXqcConst;
import jnr.constants.platform.PRIO;
import org.apache.commons.lang3.Conversion;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sound.sampled.DataLine;
import javax.swing.plaf.metal.MetalIconFactory;
import java.util.*;

@Service
public class SfcOperpServiceImpl extends ServiceImpl<SfcOperpDao, SfcOperp> implements SfcOperpService {
    /** 日志 */
    private static final Logger _logger = LoggerFactory.getLogger(SfcOperpServiceImpl.class);


    @Autowired
    private MaterialService materialService;

    @Autowired
    private SfcOperpDao sfcOperpDao;

    @Autowired
    private SfcOperpDetailDao sfcOperpDetailDao;

    @Autowired
    private IVtuzxKingdeeService vtuzxKingdeeService;

    @Autowired
    private SfcOperpService sfcOperpService;

    @Autowired
    private SfcOperpDetailService sfcOperpDetailService;

    @Autowired
    private SyncKingdeeOrderService syncKingdeeOrderService;

    @Autowired
    private SyncOrderService syncOrderService;

    @Autowired
    private SyncOrderDetailService syncOrderDetailService;

    @Autowired
    private SyncOrderDetailDao syncOrderDetailDao;

    @Override
    public IPage<SfcOperp> selectList(SfcOperpRequest request, Page<SfcOperp> page) {
        LambdaQueryWrapper<SfcOperp> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (!VtuzxUtil.isEmpty(request.getBillNo())){
            lambdaQueryWrapper.like(SfcOperp::getBillNo,request.getBillNo());
        }
        if (!VtuzxUtil.isEmpty(request.getSyncNo())){
            lambdaQueryWrapper.like(SfcOperp::getSyncNo,request.getSyncNo());
        }
        if(!VtuzxUtil.isEmpty(request.getDepartName())){
            lambdaQueryWrapper.eq(SfcOperp::getDepartName,request.getDepartName());
        }

        if (request.getCreateTime() != null){
            Date[] orderDate = request.getCreateTime();
            if(orderDate.length>0)
                lambdaQueryWrapper.ge(SfcOperp::getCreateTime, orderDate[0]);
            if(orderDate.length==2)
                lambdaQueryWrapper.le(SfcOperp::getCreateTime,DateUtils.dateToStr(orderDate[1],"yyyy-MM-dd")+ " 23:59:59");

        }
        lambdaQueryWrapper.orderByDesc(SfcOperp::getCreateTime);
        Page<SfcOperp> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
        return selectPage;
    }

    @Override
    public AjaxResult<Object> importOrder(String userName,Long user_id,List<Map<String, Object>> map) throws Exception{
        if(map==null || map.size()==0) return AjaxResult.failed(MessageUtils.message("没有获取到数据,请检查模版sheet页"));
        Map<String,Object> orderMap = new HashMap<>();//key:制令单号(单据编号)val:单据头
        Map<String,Object> detailMap = new HashMap<>();//key:制令单号(单据编号) val:单据体集合
        List<String> orderNoList = new ArrayList<>();//客户订单号集合
        //校验模板是否正确
        String headType = VtuzxUtil.getString(map.get(0),"__EMPTY");//单据类型
        String headMaterial = VtuzxUtil.getString(map.get(0),"__EMPTY_4");//物料编码
        String headTyNo = VtuzxUtil.getString(map.get(0),"生产订单");//ty件号
        String materialHeadType = VtuzxUtil.getString(map.get(0),"__EMPTY_9");//产品类型
        if (!"单据类型".equals(headType) || !"物料编码".equals(headMaterial) || !"TY件号".equals(headTyNo) || !"产品类型".equals(materialHeadType)){
            throw new RuntimeException("模板有误，请检查模板");
        }

        //前期校验excel模板数据
        Boolean aBoolean = checkSfcOperp(userName, user_id, map);
        if (!aBoolean){
            throw new RuntimeException("模板数据校验未通过,请查看传单日志查看具体信息");
        }

        //订单同步开始
        String tbbillNo = syncOrderService.startSyncOrder(userName,user_id,"生产订单");
        List<String> materialNoList = new ArrayList<>();
        List<String> departNameList = new ArrayList<>();
        //先查询出物料和车间等信息
        for (Map<String,Object>  item:map){
            String orderNo = item.get("__EMPTY_2").toString();//制令单号
            if ("制令单号".equals(orderNo)){
                continue;
            }
            String materialNo = VtuzxUtil.getString(item,"__EMPTY_4");//物料编码
            String departName = VtuzxUtil.getString(item,"__EMPTY_1");//生产车间
            if (!materialNoList.contains(materialNo)){
                materialNoList.add(materialNo);
            }
            if (!departNameList.contains(departName)){
                departNameList.add(departName);
            }
        }
        //根据物料编码查询物料名称等信息
        List<Map<String, Object>> materialList = materialService.getMaterialByNo(materialNoList);
        //将查询到的物料信息转成map
        Map<String, Object> materialToMap = changeMaterialToMap(materialList);
        //查询车间编码
        Map<String, Object> departMap = materialService.getDepartNo(departNameList);
        for (Map<String,Object>  item:map){
            String orderNo = item.get("__EMPTY_2").toString();//制令单号
            if ("制令单号".equals(orderNo)){
                continue;
            }
            if(!orderNoList.contains(orderNo)){
                orderNoList.add(orderNo);
            }
            String orderType = VtuzxUtil.getString(item,"__EMPTY");//单据类型
            String departName = VtuzxUtil.getString(item,"__EMPTY_1");//生产车间
            Integer times = VtuzxUtil.getInt(item,"__EMPTY_3");//单据日期(时间戳)
            String materialNo = VtuzxUtil.getString(item,"__EMPTY_4");//物料编码
            String tyNo = VtuzxUtil.getString(item,"生产订单");//ty件号
            Double count = VtuzxUtil.getDouble(item,"__EMPTY_5");//数量
            Integer planStart = VtuzxUtil.getInt(item,"__EMPTY_6");//计划开工时间
            Integer planEnd = VtuzxUtil.getInt(item,"__EMPTY_7");//计划完工时间
            String remark = VtuzxUtil.getString(item,"__EMPTY_8");//备注
            String materialType = VtuzxUtil.getString(item,"__EMPTY_9");//产品类型
            String BOMtype = VtuzxUtil.getString(item,"__EMPTY_10");//BOM版本
            //检验当前客户订单号是否上传过
//            Boolean checkresult = checkOrder(orderNo);
//            if (checkresult){
//                throw new RuntimeException(String.format("单据编号:%s,已经导入过,不允许重复导入",orderNo));
//            }
            SfcOperp sfcOperp = VtuzxUtil.getObject(orderMap,orderNo);
            if (null == sfcOperp){
                SfcOperp operp = new SfcOperp();
                operp.setBillNo(orderNo);
                operp.setOrderTime( conVerDate(times));
                operp.setCreateTime(new DateTime());
                operp.setType(orderType);
                operp.setRemark(remark);
                operp.setDepartName(departName);
                operp.setSyncNo(tbbillNo);//同步单号
                orderMap.put(orderNo,operp);
            }
            //map中添加详情数据
            List<SfcOperpDetail> orderDetailList = VtuzxUtil.getObject(detailMap,orderNo);
            if (null == orderDetailList || orderDetailList.size() == 0){
                List<SfcOperpDetail> orderDetails = new ArrayList<>();
                SfcOperpDetail detail = new SfcOperpDetail();
                detail.setBillNo(orderNo);
                detail.setDepartName(departName);
                //查询生产车间编码
//                String departNo = getDepartNo(departName);
                String departNo = VtuzxUtil.getString(departMap,departName);
                detail.setDepartNo(departNo);
                //查询规格等信息
//                Map<String,Object> materialMap = getMaterial(materialNo);
                Map<String,Object> materialMap = VtuzxUtil.getObject(materialToMap,materialNo);
                if (!VtuzxUtil.isEmpty(materialMap)){
                    detail.setMaterialNo(materialNo);
                    detail.setMaterialName(VtuzxUtil.getString(materialMap,"materialName"));
                    detail.setSpecification(VtuzxUtil.getString(materialMap,"FSpecification"));
                    detail.setUnitName(VtuzxUtil.getString(materialMap,"unitName"));
                    detail.setUnitNo(VtuzxUtil.getString(materialMap,"unitNo"));
                }
                detail.setQty(count);
                detail.setPlanStart(conVerDate(planStart));
                detail.setPlanEnd(conVerDate(planEnd));
                detail.setMaterialType(materialType);
                detail.setBOMType(BOMtype);
                orderDetails.add(detail);
                detailMap.put(orderNo,orderDetails);
            } else {
                SfcOperpDetail detail = new SfcOperpDetail();
                detail.setBillNo(orderNo);
                detail.setDepartName(departName);
                //查询生产车间编码
                String departNo = VtuzxUtil.getString(departMap,departName);
                detail.setDepartNo(departNo);
                //查询规格等信息
                Map<String,Object> materialMap = VtuzxUtil.getObject(materialToMap,materialNo);
                if (!VtuzxUtil.isEmpty(materialMap)){
                    detail.setMaterialNo(materialNo);
                    detail.setMaterialName(VtuzxUtil.getString(materialMap,"materialName"));
                    detail.setSpecification(VtuzxUtil.getString(materialMap,"FSpecification"));
                    detail.setUnitName(VtuzxUtil.getString(materialMap,"unitName"));
                    detail.setUnitNo(VtuzxUtil.getString(materialMap,"unitNo"));
                }
                detail.setQty(count);
                detail.setPlanStart(conVerDate(planStart));
                detail.setPlanEnd(conVerDate(planEnd));
                detail.setMaterialType(materialType);
                detail.setBOMType(BOMtype);
                orderDetailList.add(detail);
                detailMap.put(orderNo,orderDetailList);
            }

        }
        //查询已经保存过的生产订单
        List<String> saveOrderNoList =  selectOperpByOrderNo(orderNoList);
        //数据库批量保存数据
        boolean saveBatch = saveBatchOperp(orderMap,detailMap,orderNoList,saveOrderNoList);

        List<SyncOrderDetail> orderDetailList = new ArrayList<>();//需要保存到传单日志详情表中的数据
        for (String orderNo: orderNoList){
            //根据订单编号查询传单日志表
                SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail.setOrderNo(orderNo);
                syncOrderDetail.setBillNo(tbbillNo);
                syncOrderDetail.setCreateTime(new Date());
                syncOrderDetail.setUpdateTime(new Date());
//            Boolean checkresult = checkOrder(orderNo);
            Boolean checkresult = saveOrderNoList.contains(orderNo);
            if (checkresult){
                syncOrderDetail.setMessage(String.format("单据编号:%s,已经导入过,不允许重复导入",orderNo));
                syncOrderDetail.setIsSuccess(false);
                orderDetailList.add(syncOrderDetail);
                continue;
            }


            SfcOperp sfcOperp = VtuzxUtil.getObject(orderMap,orderNo);
            List<SfcOperpDetail> sfcOperpDetailList = VtuzxUtil.getObject(detailMap,orderNo);
            //数据库保存数据
//            boolean saveBatch = saveSfcOperp(sfcOperp, sfcOperpDetailList);
            try {
                syncKingdeeOrderService.syncPrdOrder(sfcOperp, sfcOperpDetailList,user_id);
                syncOrderDetail.setIsSuccess(true);
            } catch (Exception e){
                //捕获异常删除已经保存的数据
                deleteSfcOperp(sfcOperp,sfcOperpDetailList);
                _logger.info(e.getMessage());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage(e.getMessage());

            }
            orderDetailList.add(syncOrderDetail);
        }
        Map<String, Object> data = syncOrderService.endSyncOrder(orderDetailList, tbbillNo);
        return AjaxResult.success(data);
    }


    /**
     * 查询已经保存过的生产订单
     * @param orderNoList
     * @return
     */
    private List<String> selectOperpByOrderNo(List<String> orderNoList) {
        LambdaQueryWrapper<SfcOperp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SfcOperp::getBillNo,orderNoList);
        List<SfcOperp> sfcOperpList = sfcOperpDao.selectList(queryWrapper);
        List<String>  saveOrderNoList = new ArrayList<>();
        if (!VtuzxUtil.isEmpty(sfcOperpList)){
            for (SfcOperp  sfcOperp : sfcOperpList){
                String billNo = sfcOperp.getBillNo();
                if (!saveOrderNoList.contains(billNo)){
                    saveOrderNoList.add(billNo);
                }
            }
        }

        return saveOrderNoList;
    }
    private boolean saveBatchOperp(Map<String, Object> orderMap, Map<String, Object> detailMap, List<String> orderNoList,List<String> saveOrderNoList) {

        List<SfcOperp> sfcOperpList = new ArrayList<>();
        List<SfcOperpDetail> detailList = new ArrayList<>();
        for (String orderNo : orderNoList){
            //如果之前上传过跳过循环
            if (saveOrderNoList.contains(orderNo)){
                continue;
            }

            SfcOperp sfcOperp = VtuzxUtil.getObject(orderMap,orderNo);
            List<SfcOperpDetail> sfcOperpDetailList = VtuzxUtil.getObject(detailMap,orderNo);
            sfcOperpList.add(sfcOperp);
            detailList.addAll(sfcOperpDetailList);
        }
        boolean b = sfcOperpService.saveOrUpdateBatch(sfcOperpList);
        boolean r = sfcOperpDetailService.saveOrUpdateBatch(detailList);
        return b && r;
    }


    /**
     * 校验销售订单导入的数据
     * @param user_id
     * @param map
     * @return
     * @throws Exception
     */
    private Boolean checkSfcOperp(String userName,Long user_id,List<Map<String,Object>> map) throws Exception{
        //添加行号
        int i = 3;
        for (Map<String,Object> data : map){
            data.put("line",i);
            i++;
        }
        //添加之前做一个删除
        materialService.deleteOperpOrder(userName,user_id);
        //sqlserver数据库添加当前导入的数据
        materialService.saveSfcOperp(userName,user_id,map);
        //校验指令单号
        List<Map<String,Object>> checkCusBill =  materialService.checkOperpBillNo(user_id);
        //校验物料
        List<Map<String,Object>> checkMaterial =  materialService.checkOperpMaterial(user_id);
        //校验bom
        List<Map<String,Object>> checkBom =  materialService.checkOperpBom(user_id);

        //校验车间
        List<Map<String,Object>> checkWorkShop =  materialService.checkOperpWorkShop(user_id);

        //校验单据日期
        List<Map<String,Object>> checkOrderTime =  materialService.checkOperpOrderTime(user_id);

        //校验开工日期
        List<Map<String,Object>> checkOperpStartTime =  materialService.checkOperpStartTime(user_id);
        //校验完工时间
        List<Map<String,Object>> checkOperpEndTime =  materialService.checkOperpEndTime(user_id);


        //判断查询的数据如果都为空的话说明模板数据校验通过可以导入,如果不为空的话添加日志信息并且停止传单
        if (VtuzxUtil.isEmpty(checkCusBill) &&  VtuzxUtil.isEmpty(checkMaterial) && VtuzxUtil.isEmpty(checkBom)
                && VtuzxUtil.isEmpty(checkWorkShop) && VtuzxUtil.isEmpty(checkOrderTime)
                && VtuzxUtil.isEmpty(checkOperpStartTime) && VtuzxUtil.isEmpty(checkOperpEndTime)){
            return true;
        }  else {//有一个不等于空的就说明有问题,需要向日志中添加信息
            saveOperpLog(userName,user_id,checkCusBill,checkMaterial,checkBom,checkWorkShop,checkOrderTime,checkOperpStartTime,checkOperpEndTime);
            return false;
        }

    }

    /**
     * 模板级校验添加日志信息
     * @param checkCusBill
     * @param checkMaterial

     */
    private void saveOperpLog(String userName,Long user_id,List<Map<String,Object>> checkCusBill,List<Map<String,Object>> checkMaterial,List<Map<String,Object>> checkBom,
                              List<Map<String,Object>> checkWorkShop,List<Map<String,Object>> checkOrderTime,List<Map<String,Object>> checkOperpStartTime,List<Map<String,Object>> checkOperpEndTime){
        String tbbillNo = syncOrderService.startSyncOrder(userName,user_id,"生产订单模板级校验");
        List<SyncOrderDetail> orderDetailList = new ArrayList<>();
        if (!VtuzxUtil.isEmpty(checkCusBill)){//指令单号校验
            for (Map<String,Object> data : checkCusBill){
                int line = VtuzxUtil.getInt(data,"LINE");//行号
                SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail.setOrderNo("生产订单模板级校验");//客户订单号
                syncOrderDetail.setBillNo(tbbillNo);
                syncOrderDetail.setCreateTime(new Date());
                syncOrderDetail.setUpdateTime(new Date());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage("第" + line + "行的指令单号不允许为空");
                orderDetailList.add(syncOrderDetail);
            }
        }

        if (!VtuzxUtil.isEmpty(checkMaterial)){//物料校验
            for (Map<String,Object> data : checkMaterial){
                int line = VtuzxUtil.getInt(data,"LINE");//行号
                SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail.setOrderNo("生产订单模板级校验");//客户订单号
                syncOrderDetail.setBillNo(tbbillNo);
                syncOrderDetail.setCreateTime(new Date());
                syncOrderDetail.setUpdateTime(new Date());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage("第" + line + "行的物料编码未审核,或者不存在,或者已禁用,或者不允许生产请确认");
                orderDetailList.add(syncOrderDetail);
            }
        }
        if (!VtuzxUtil.isEmpty(checkBom)){//BOM校验
            for (Map<String,Object> data : checkBom){
                int line = VtuzxUtil.getInt(data,"LINE");//行号
                SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail.setOrderNo("生产订单模板级校验");//客户订单号
                syncOrderDetail.setBillNo(tbbillNo);
                syncOrderDetail.setCreateTime(new Date());
                syncOrderDetail.setUpdateTime(new Date());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage("第" + line + "行的BOM版本未审核,或者不存在,或者已禁用,请确认");
                orderDetailList.add(syncOrderDetail);
            }
        }

        if (!VtuzxUtil.isEmpty(checkWorkShop)){//车间校验
            for (Map<String,Object> data : checkWorkShop){
                int line = VtuzxUtil.getInt(data,"LINE");//行号
                SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail.setOrderNo("生产订单模板级校验");//客户订单号
                syncOrderDetail.setBillNo(tbbillNo);
                syncOrderDetail.setCreateTime(new Date());
                syncOrderDetail.setUpdateTime(new Date());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage("第" + line + "行的车间不能为空,或者不存在,或者已禁用,请确认");
                orderDetailList.add(syncOrderDetail);
            }
        }

        if (!VtuzxUtil.isEmpty(checkOrderTime)){//车间校验
            for (Map<String,Object> data : checkOrderTime){
                int line = VtuzxUtil.getInt(data,"LINE");//行号
                SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail.setOrderNo("生产订单模板级校验");//客户订单号
                syncOrderDetail.setBillNo(tbbillNo);
                syncOrderDetail.setCreateTime(new Date());
                syncOrderDetail.setUpdateTime(new Date());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage("第" + line + "行的单据日期不能为空");
                orderDetailList.add(syncOrderDetail);
            }
        }

        if (!VtuzxUtil.isEmpty(checkOperpStartTime)){//开工时间
            for (Map<String,Object> data : checkOperpStartTime){
                int line = VtuzxUtil.getInt(data,"LINE");//行号
                SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail.setOrderNo("生产订单模板级校验");//客户订单号
                syncOrderDetail.setBillNo(tbbillNo);
                syncOrderDetail.setCreateTime(new Date());
                syncOrderDetail.setUpdateTime(new Date());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage("第" + line + "行的计划开工时间不能为空,不能小于单据日期,不能大于计划完工时间");
                orderDetailList.add(syncOrderDetail);
            }
        }

        if (!VtuzxUtil.isEmpty(checkOperpEndTime)){//完工时间
            for (Map<String,Object> data : checkOperpEndTime){
                int line = VtuzxUtil.getInt(data,"LINE");//行号
                SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
                syncOrderDetail.setOrderNo("生产订单模板级校验");//客户订单号
                syncOrderDetail.setBillNo(tbbillNo);
                syncOrderDetail.setCreateTime(new Date());
                syncOrderDetail.setUpdateTime(new Date());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage("第" + line + "行的计划完工时间不能为空,不能小于单据日期,不能小于计划开工时间");
                orderDetailList.add(syncOrderDetail);
            }
        }

        syncOrderService.endSyncOrder(orderDetailList,tbbillNo);
    }
    /**
     * key;物料编码 val:物料相关信息(map)
     * @param materialList
     * @return
     */
    private Map<String,Object> changeMaterialToMap(List<Map<String,Object>> materialList){
        Map<String,Object> dataMap = new HashMap<>();
        for (Map<String,Object> data : materialList){
            String FNUMBER = VtuzxUtil.getString(data,"FNUMBER");
            String FNAME = VtuzxUtil.getString(data,"FNAME");
            String FSPECIFICATION = VtuzxUtil.getString(data,"FSPECIFICATION");
            String unitNo = VtuzxUtil.getString(data,"unitNo");//单位编码
            String unitName = VtuzxUtil.getString(data,"unitName");//单位名称
            String FDOCUMENTSTATUS = VtuzxUtil.getString(data,"FDOCUMENTSTATUS");//审核状态
            String FFORBIDSTATUS = VtuzxUtil.getString(data,"FFORBIDSTATUS");//禁用状态
            Map<String,Object> materialMap = new HashMap<>();
            materialMap.put("FNUMBER",FNUMBER);
            materialMap.put("FNAME",FNAME);
            materialMap.put("FSPECIFICATION",FSPECIFICATION);
            materialMap.put("unitNo",unitNo);
            materialMap.put("unitName",unitName);
            materialMap.put("FDOCUMENTSTATUS",FDOCUMENTSTATUS);
            materialMap.put("FFORBIDSTATUS",FFORBIDSTATUS);
            dataMap.put(FNUMBER,materialMap);
        }
        return dataMap;
    }

    @Override
    public Map<String, Object> deleteSfcoperp(Map<String, Object> map) throws Exception {
        String billNoList = map.get("billNo").toString();
        //根据逗号拆分成数组
        int headCount = 0;
        int detailCount =0;
        String[] split = billNoList.split(",");
        for (String idNo : split){
            SfcOperp sfcOperp = sfcOperpDao.selectById(idNo);
            String billNo = sfcOperp.getBillNo();
            VtuzxKingdeeCloudClient client = vtuzxKingdeeService.loginKingdee();
            //查询金蝶生产订单
            List<VtuzxMap> prdcumQuery = vtuzxKingdeeService.query(client,"PRD_MO", new VtuzxArrayList<>(
                            "FBillNo"
                    ),
                    // 组合两个过滤条件（规格型号 + 物料分组）
                    String.format("FBillNo = '%s' ",
                            billNo), null, 0, 0);

            if (!VtuzxUtil.isEmpty(prdcumQuery)) {
                throw new RuntimeException(String.format("该订单已存在不能删除订单号%s", billNo));
            }
            // 删除本地数据库记录
        int deletedDetails = sfcOperpDao.delete(
                new LambdaQueryWrapper<SfcOperp>()
                        .eq(SfcOperp::getBillNo, billNo)
        );
            headCount += deletedDetails;
        int deletedMain = sfcOperpDetailDao.delete(
                new LambdaQueryWrapper<SfcOperpDetail>()
                        .eq(SfcOperpDetail::getBillNo, billNo)
        );
            detailCount += deletedMain;
        }
        Map<String, Object> data = new HashMap<>();
        data.put("success", true);
        data.put("message", String.format("主表删除 %d 条，明细表删除 %d 条", headCount, detailCount));
        return data;
    }

    @Override
    public AjaxResult<Object> workList(Long user_id) throws Exception {
        VtuzxKingdeeCloudClient client = null;
        try {
            client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
        } catch (Exception e){
            throw new RuntimeException("金蝶账号或密码错误,请修改自己的金蝶密码");
        }
        List<VtuzxMap> workList = new ArrayList<>();
        //查询金蝶及时库存在当前仓位是否足够
        List<VtuzxMap> departQuery = vtuzxKingdeeService.query(client, "BD_Department", new VtuzxArrayList<>(
                        "Fnumber",
                        "FName"
                ),
               ("FName like '%车间%'"), null, 0, 0);//根据物料仓库查询数量
        if (!VtuzxUtil.isEmpty(departQuery)) {
            for (VtuzxMap department : departQuery){
                String departName = VtuzxUtil.getString(department,"FName");
                String departNo = VtuzxUtil.getString(department,"Fnumber");
                VtuzxMap data = new VtuzxMap();
                data.append("departName",departName)
                        .append("departNo",departNo);
                workList.add(data);
            }
        }
        return AjaxResult.success(workList);
    }

    /**
     * 导入生产订单变更单
     * @param userName
     * @param user_id
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public AjaxResult<Object> importOrderUpdate(String userName, Long user_id, List<Map<String, Object>> map) throws Exception {
        if(map==null || map.size()==0) return AjaxResult.failed(MessageUtils.message("没有获取到数据,请检查模版sheet页"));
        Map<String,Object> orderMap = new HashMap<>();//key:制令单号(单据编号)val:单据头
        Map<String,Object> detailMap = new HashMap<>();//key:制令单号(单据编号) val:单据体集合
        List<String> orderNoList = new ArrayList<>();//客户订单号集合
        //校验模板是否正确
        String headType = VtuzxUtil.getString(map.get(0),"__EMPTY");//单据类型
        String headMaterial = VtuzxUtil.getString(map.get(0),"__EMPTY_4");//物料编码
        String headTyNo = VtuzxUtil.getString(map.get(0),"生产订单");//ty件号
        String materialHeadType = VtuzxUtil.getString(map.get(0),"__EMPTY_9");//产品类型
        if (!"单据类型".equals(headType) || !"物料编码".equals(headMaterial) || !"TY件号".equals(headTyNo) || !"产品类型".equals(materialHeadType)){
            throw new RuntimeException("模板有误，请检查模板");
        }

        //前期校验excel模板数据
//        Boolean aBoolean = checkSfcOperp(userName, user_id, map);
//        if (!aBoolean){
//            throw new RuntimeException("模板数据校验未通过,请查看传单日志查看具体信息");
//        }

        //订单同步开始
        String tbbillNo = syncOrderService.startSyncOrder(userName,user_id,"生产订单变更");
        Map<String,Object> countMap = new HashMap<>();//key:订单号+物料编码 val:变更的数量
        for (Map<String,Object>  item:map){
            String orderNo = item.get("__EMPTY_2").toString();//制令单号
            if ("制令单号".equals(orderNo)){
                continue;
            }
            if(!orderNoList.contains(orderNo)){
                orderNoList.add(orderNo);
            }
            String orderType = VtuzxUtil.getString(item,"__EMPTY");//单据类型
            String departName = VtuzxUtil.getString(item,"__EMPTY_1");//生产车间
            Integer times = VtuzxUtil.getInt(item,"__EMPTY_3");//单据日期(时间戳)
            String materialNo = VtuzxUtil.getString(item,"__EMPTY_4");//物料编码
            String tyNo = VtuzxUtil.getString(item,"生产订单");//ty件号
            Double count = VtuzxUtil.getDouble(item,"__EMPTY_5");//数量
            Integer planStart = VtuzxUtil.getInt(item,"__EMPTY_6");//计划开工时间
            Integer planEnd = VtuzxUtil.getInt(item,"__EMPTY_7");//计划完工时间
            String remark = VtuzxUtil.getString(item,"__EMPTY_8");//备注
            String materialType = VtuzxUtil.getString(item,"__EMPTY_9");//产品类型
            String BOMtype = VtuzxUtil.getString(item,"__EMPTY_10");//BOM版本
            countMap.put(orderNo + "_" + materialNo,count);
        }
        //查询已经保存过的生产订单
        List<String> saveOrderNoList =  selectOperpByOrderNo(orderNoList);
        Map<String, Object> orderToMap = selectOrderToMap(orderNoList);//单据头mp
        Map<String, Object> detailToMap = selectOrderDetailToMap(orderNoList);//单据体map

        List<SfcOperpDetail> updateOperpDetailList = new ArrayList<>();//需要修改的详情集合
        List<SyncOrderDetail> orderDetailList = new ArrayList<>();//需要保存到传单日志详情表中的数据
        for (String orderNo: orderNoList){
            //根据订单编号查询传单日志表
            SyncOrderDetail syncOrderDetail = new SyncOrderDetail();
            syncOrderDetail = new SyncOrderDetail();
            syncOrderDetail.setOrderNo(orderNo);
            syncOrderDetail.setBillNo(tbbillNo);
            syncOrderDetail.setCreateTime(new Date());
            syncOrderDetail.setUpdateTime(new Date());
            Boolean checkresult = saveOrderNoList.contains(orderNo);
            if (!checkresult){//如果订单没有上传给提示
                syncOrderDetail.setMessage(String.format("单据编号:%s,没有导入过,无法变更",orderNo));
                syncOrderDetail.setIsSuccess(false);
                orderDetailList.add(syncOrderDetail);
                continue;
            }

            SfcOperp sfcOperp = VtuzxUtil.getObject(orderToMap,orderNo);
            List<SfcOperpDetail> sfcOperpDetailList = VtuzxUtil.getObject(detailToMap,orderNo);


            try {
                syncKingdeeOrderService.syncPrdOrderUpdate(sfcOperp, sfcOperpDetailList,user_id,countMap);
                syncOrderDetail.setIsSuccess(true);
                //变更单上传成功的话修改详情表中的数据
                updateOperpDetailList.addAll(sfcOperpDetailList);
            } catch (Exception e){

                _logger.info(e.getMessage());
                syncOrderDetail.setIsSuccess(false);
                syncOrderDetail.setMessage(e.getMessage());

            }
            orderDetailList.add(syncOrderDetail);
        }
        Map<String, Object> data = syncOrderService.endSyncOrder(orderDetailList, tbbillNo);
        return AjaxResult.success(data);
    }


    /**
     * 查询生产订单单据头整理成map
     * @param orderNoList
     * @return
     */
    private Map<String,Object> selectOrderToMap(List<String> orderNoList) {
        LambdaQueryWrapper<SfcOperp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SfcOperp::getBillNo,orderNoList);
        List<SfcOperp> sfcOperpList = sfcOperpDao.selectList(queryWrapper);
        Map<String,Object> orderMap = new HashMap<>();//key;订单号 val:生产订单单据头信息
        if (!VtuzxUtil.isEmpty(sfcOperpList)){
            for (SfcOperp  sfcOperp : sfcOperpList){
                String billNo = sfcOperp.getBillNo();
                orderMap.put(billNo,sfcOperp);
            }
        }

        return orderMap;
    }

    /**
     * 查询生产订单单据体整理成map
     * @param orderNoList
     * @return
     */
    private Map<String,Object> selectOrderDetailToMap(List<String> orderNoList) {
        LambdaQueryWrapper<SfcOperpDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SfcOperpDetail::getBillNo,orderNoList);
        List<SfcOperpDetail> detailList = sfcOperpDetailDao.selectList(queryWrapper);
        Map<String,Object> dataMap = new HashMap<>();//key;订单号 val:List<生产订单单据体信息>
        if (!VtuzxUtil.isEmpty(detailList)){
            for (SfcOperpDetail  sfcOperpDetail : detailList){
                String billNo = sfcOperpDetail.getBillNo();
                List<SfcOperpDetail> mapList = VtuzxUtil.getObject(dataMap,billNo);
                if (!VtuzxUtil.isEmpty(mapList)){
                    mapList.add(sfcOperpDetail);
                    dataMap.put(billNo,mapList);
                } else {//如果当前map中没有
                    mapList = new ArrayList<>();
                    mapList.add(sfcOperpDetail);
                    dataMap.put(billNo,mapList);
                }
            }
        }

        return dataMap;
    }


    /**
     * 校验生产订单是否上传过
     * @param orderNo
     * @return
     */
    private Boolean checkOrder (String orderNo){
        LambdaQueryWrapper<SfcOperp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SfcOperp::getBillNo,orderNo);
        SfcOperp sfcOperp = sfcOperpDao.selectOne(queryWrapper);
        if(sfcOperp != null){
            return true;
        }else {
            return false;
        }
    }

    /**
     * Excel日期转换
     * @param times
     * @return
     */
    public Date conVerDate(int times){
        Calendar calendar = Calendar.getInstance();
        calendar.set(1900,Calendar.JANUARY,1);
        calendar.add(Calendar.DAY_OF_MONTH,times -2);
        Date date = calendar.getTime();
        return date;
    }

    private String getDepartNo (String departName) throws Exception{
        String departNo = "";
        VtuzxKingdeeCloudClient client = vtuzxKingdeeService.loginKingdee();
        //查询金蝶及时库存在当前仓位是否足够
        List<VtuzxMap> departQuery = vtuzxKingdeeService.query(client, "BD_Department", new VtuzxArrayList<>(
                        "Fnumber"
                ),
                String.format("FName = '%s'", departName), null, 0, 1);//根据物料仓库查询数量
        if (!VtuzxUtil.isEmpty(departQuery)) {
            departNo =VtuzxUtil.getString(departQuery.get(0),"Fnumber");
        } else {
//            throw new RuntimeException(String.format("金蝶不存在生产车间:%s",departName));
            _logger.info(String.format("金蝶不存在生产车间:%s",departName));
        }

        return departNo;
    }

    private Map<String, Object> getMaterial (String materialNo) throws Exception{
        Map<String,Object> materialMap = new HashMap<>();
        VtuzxKingdeeCloudClient client = vtuzxKingdeeService.loginKingdee();
        //查询金蝶及时库存在当前仓位是否足够
        List<VtuzxMap> departQuery = vtuzxKingdeeService.query(client, "BD_MATERIAL", new VtuzxArrayList<>(
                        "FName",
                        "FSpecification",
                        "FBaseUnitId.FName",
                        "FBaseUnitId.FNumber"

                ),
                String.format("FNumber = '%s'", materialNo), null, 0, 1);//根据物料仓库查询数量
        if (!VtuzxUtil.isEmpty(departQuery)) {
            String materialName =VtuzxUtil.getString(departQuery.get(0),"FName");
            String FSpecification =VtuzxUtil.getString(departQuery.get(0),"FSpecification");
            String unitName =VtuzxUtil.getString(departQuery.get(0),"FBaseUnitId.FName");
            String unitNo =VtuzxUtil.getString(departQuery.get(0),"FBaseUnitId.FNumber");
            materialMap.put("materialName",materialName);
            materialMap.put("FSpecification",FSpecification);
            materialMap.put("unitName",unitName);
            materialMap.put("unitNo",unitNo);
        } else {
//            throw new RuntimeException(String.format("金蝶不存物料编码:%s",materialNo));
            _logger.info(String.format("金蝶不存物料编码:%s",materialNo));
        }
        return materialMap;
    }

    /**
     * 保存生产订单的信息
     * @param
     * @param
     * @return
     */
    private Boolean saveSfcOperp(SfcOperp sfcOperp,List<SfcOperpDetail> detailList){

        boolean saveBatch = sfcOperpService.save(sfcOperp);
        boolean detailBatch = sfcOperpDetailService.saveOrUpdateBatch(detailList);
        return saveBatch && detailBatch;
    }

    private void deleteSfcOperp (SfcOperp sfcOperp, List<SfcOperpDetail> sfcOperpDetailList){
        List<Long> detailIdList = new ArrayList<>();

        for (SfcOperpDetail detail : sfcOperpDetailList){
            Long id = detail.getId();
            if (!detailIdList.contains(id)){
                detailIdList.add(id);
            }
        }
        sfcOperpService.removeById(sfcOperp.getId());
        sfcOperpDetailService.removeBatchByIds(detailIdList);
    }
}
